<?php


namespace Buu\Modules\EventSystem\Controllers;

use App\Library\EventCommon;
use App\Models\ApiUrl;
use App\Models\Event;
use Encore\Admin\Form;
use Encore\Admin\Form\NestedForm;
use Encore\Admin\Grid;
use App\Models\Consumer;
use App\Models\SubEvent;
use Illuminate\Http\Request;
use App\Models\EventLatitude;
use App\Models\EventProperty;
use App\Pockets\GridDataModel;
use App\Models\ConsumerChannel;
use Encore\Admin\Facades\Admin;
use Encore\Admin\Widgets\Table;
use App\Models\SubEventProperty;
use Encore\Admin\Layout\Content;
use App\Models\BasicEventLatitude;
use Illuminate\Support\MessageBag;
use Encore\Admin\Controllers\AdminController;
use Encore\Admin\Widgets\Tab;

class ConsumerController extends AdminController
{
    protected $title = '消费者';


    public function api($basic_event_latitude_id, Request $request)
    {
        $event_id = $request->input('q');
        // --- 获取事件属性 ---
        $event_latitude = EventLatitude::where([
            'event_id' => $event_id,
            'basic_event_latitude_id' => $basic_event_latitude_id
        ])->get()->toArray();

        $event_latitude_ids = empty($event_latitude) ? [] : array_column($event_latitude, 'id');

        $event = empty($event_latitude_ids) ? [] : EventProperty::where(['event_id' => $event_id])->whereIn(
            'event_latitude_id',
            $event_latitude_ids
        )->get()->toArray();

        $options = [];

        foreach ($event as $v) {
            $options[] = [
                'id' => $v['id'],
                'text' => $v['name'],
            ];
        }

        return response()->json($options);
    }

    public function index(Content $content)
    {
        $content->title($this->title())
            ->description($this->description['index'] ?? trans('admin.list'))
            ->breadcrumb([
                'text' => $this->title
            ]);
        $tab = new Tab();
        $tab->add('事件系统', $this->grid(Consumer::TYPE_SORTING_HAT));
        $tab->add('异步任务', $this->grid(Consumer::TYPE_SYNC_QUEUE));
        return $content->body($tab);
    }

    /**
     * 消费者的事件绑定
     */
    public function config($id, Content $content)
    {
        $consumerId = $id;
        $form = new Form(new Consumer);
        $form->footer(function (Form\Footer $footer) {
            $footer->disableEditingCheck();
            $footer->disableCreatingCheck();
            $footer->disableViewCheck();
        });
        $form->tools(function (Form\Tools $tools) {
            $tools->disableDelete();
            $tools->disableView();
        });

        $event_ids = SubEvent::query()->where([
            'consumer_id' => $id,
            'data_status' => SubEvent::STATUS_ON
        ])->get()->pluck('event_id')->toArray();

        $event_latitude = EventLatitude::query()->whereIn('event_id', $event_ids)->get()->toArray();
        $event_latitude_map = empty($event_latitude) ? [] : array_column(
            $event_latitude,
            'basic_event_latitude_id',
            'id'
        );
        $event_latitude_ids = empty($event_latitude) ? [] : array_column($event_latitude, 'id');

        $event = empty($event_latitude_ids) ? [] : EventProperty::query()->whereIn(
            'event_latitude_id',
            $event_latitude_ids
        )->get()->toArray();

        $options = [];
        foreach ($event as $v) {
            $options[$v['event_id']][$event_latitude_map[$v['event_latitude_id']]][$v['id']] = $v['name'];
        }
        $form->table('events', '事件选择', function (NestedForm $nest) use ($options, $event_ids, $consumerId) {
            // 所有定义的事件
            $allEvents = Event::all()->pluck('name', 'id')->toArray();
            // 事件基础维度
            $latitude = BasicEventLatitude::all()->pluck('name', 'id')->toArray();
            $ids = array_keys($latitude);
            $sourceUrl = array_map(function ($v) {
                return route('consumer.api', ['basic_event_latitude_id' => $v]);
            }, $ids);
            $keyArr = array_combine(
                $ids,
                array_map(function ($v) {
                    return 'key' . $v;
                }, $ids)
            );
            $nest->hidden('consumer_id')->default($consumerId);
            $nest->select('event_id', '事件名称')->options($allEvents)->loads($keyArr, $sourceUrl);
            foreach ($latitude as $id => $name) {
                $nest->multipleSelect(
                    $keyArr[$id],
                    $name
                )->options($options[$event_ids[$nest->getKey()] ?? 0][$id] ?? []);
            }
        });
        $form->setAction(route('consumer.config', [$id]));
        $form->saving(function (Form $form) {
        });
        $form->saved(function (Form $form) {
        });

        return $content
            ->title($this->title())
            ->description('事件选择')
            ->body($form->edit($id));
    }

    /**
     * 消费者的事件绑定, 保存数据
     */
    public function configSave($consumerId, Request $request)
    {
        try {
            $all = $request->all();
            $events = $all['events'] ?? [];
            $old = SubEvent::where([
                'consumer_id' => $consumerId,
                'data_status' => SubEvent::STATUS_ON
            ])->get()->toArray();
            $old_sub_event_ids = array_column($old, 'id');

            $extra_params['add_username'] = Admin::user()->username;
            Consumer::eventConfigSave($consumerId, $events, $old_sub_event_ids, $extra_params);

            $success = new MessageBag([
                'title' => '订阅事件成功'
            ]);

            return redirect('/admin/EventSystem/consumer')->with(compact('success'));
        } catch (\Exception $e) {
            $error = new MessageBag([
                'title' => '操作失败,信息:' . $e->getMessage()
            ]);
            return back()->withInput()->with(compact('error'));
        }
    }


    /**
     * 消费者列表
     */
    protected function grid($type)
    {
        $grid = new Grid(new Consumer());
        $grid->model()->where('type', $type);
        $grid->paginate(50);
        $grid->disableFilter();
        $grid->disableExport();
        $grid->column('id', 'ID');
        $grid->column('name', '消费者');
        $grid->column('consumer_channel_id', '分发者')->using(
            ConsumerChannel::getAll()->pluck(
                'name',
                'id'
            )->toArray()
        )->label();
        $grid->column('type', '消费者类型')->using(Consumer::TYPE_LIST);
        $grid->column('api_url', '消费域名')->display(function ($api_url) {
            return $api_url['name'] ?? '';
        })->modal('域名配置', function ($modal) {
            if ($modal->api_url) {
                $apiUrl = $modal->api_url->toArray();
            } else {
                $apiUrl = [];
            }
            return new Table(['字段名', '值'], $apiUrl);
        });
        if ($type == Consumer::TYPE_SORTING_HAT) {
            $grid->column('uri', 'uri');
            $grid->column('event', '订阅事件')->display(function () {
                $eventIds = SubEvent::where('consumer_id', $this->id)->pluck('event_id');
                return Event::find($eventIds)->pluck('name');
            })->label();
            $grid->column('task_type', '远程任务类型')->using(Consumer::TASK_TYPE, '未知')->label([
                Consumer::TASK_DEFAULT => 'default',
                Consumer::TASK_DAILY => 'warning',
                Consumer::TASK_MONTHLY => 'success',
                Consumer::TASK_EVERY_YEAR => 'info',
            ]);
        } else {
            $grid->column('rabbitmq_vhost', 'rabbitmq vhost');
            $grid->column('rabbitmq_queue', 'rabbitmq queue');
        }
        $grid->column('admin_username', '服务负责人');
        $grid->actions(function (Grid\Displayers\Actions $actions) use ($type) {
            if ($type == Consumer::TYPE_SORTING_HAT) {
                if ($actions->row->task_type != Consumer::TASK_DEFAULT) {
                    $actions->prepend(
                        "<a href='consumer/{$actions->row->id}/setConfig'><i class='fa fa-cogs'></i> 订阅事件查看</a>"
                    );
                } else {
                    $actions->prepend(
                        "<a href='consumer/{$actions->row->id}/config'><i class='fa fa-cogs'></i> 订阅事件设置</a>"
                    );
                }
            }
            if ($actions->row->delete_time != 0) {
                $actions->append("<span style=\"color:red\">已删除</span>");
                $actions->disableDelete();
                $actions->disableEdit();
            }
        });

        return $grid->render();
    }

    /**
     * 消费者表单
     */
    protected function form(): Form
    {
        require_once '/data/wwwroot/g_vendor/autoload.php';
        $form = new Form(new Consumer);

        $form->footer(function (Form\Footer $footer) {
            $footer->disableEditingCheck();
            $footer->disableCreatingCheck();
            $footer->disableViewCheck();
        });
        $form->tools(function (Form\Tools $tools) {
            $tools->disableDelete();
            $tools->disableView();
        });
        $form->text('name', '消费者')->placeholder('请输入消费者')->setWidth(4, 2)->required();
        $form->select('consumer_channel_id', '分发者')->options(
            ConsumerChannel::getAll()->pluck(
                'name',
                'id'
            )
        )->required();
        $form->select('api_url_id', '消费域名')->options(
            ApiUrl::query()->where('status', ApiUrl::STATUS_ON)->pluck('name', 'id')->toArray()
        )->required();
        $form->radio('type', '消费者类型')
            ->options(Consumer::TYPE_LIST)
            ->when(Consumer::TYPE_SORTING_HAT, function (Form $form) {
                $form->select('task_type', '远程关联')->options(Consumer::TASK_TYPE);
                $form->text('uri', 'uri');
            })->when(Consumer::TYPE_SYNC_QUEUE, function (Form $form) {
                $form->radio('request_type', '请求格式')->options(Consumer::REQUEST_TYPE_LIST)->default(Consumer::REQUEST_TYPE_RAW);
                $form->text('rabbitmq_vhost', 'rabbitmq_vhost');
                $form->text('rabbitmq_queue', 'rabbitmq_queue');
                $form->text('rabbitmq_routing_key', 'rabbitmq_routing_key');
                $form->text('rabbitmq_exchange_type', 'rabbitmq_exchange_type');
                $form->text('rabbitmq_exchange', 'rabbitmq_exchange');
            });

        $form->select('admin_username', '服务负责人')->options(Admin::user()->all()->pluck('name', 'username'))->default(
            Admin::user()->username
        );
        $form->saving(function (Form $form) {
            if ($form->task_type != Consumer::TASK_DEFAULT) {
                $count = Consumer::query()->where([
                    'task_type' => $form->task_type,
                    'data_status' => Consumer::STATUS_NORMAL
                ])->count('id');
                if ($count > 1) {
                    $error = new MessageBag([
                        'title' => '每个远程关联只能关联一个消费者'
                    ]);
                    return back()->with(compact('error'))->withInput();
                }
            }


            if ($form->model()->id > 0) {
                $form->update_time = time();
            } else {
                $form->add_time = time();
                $form->update_time = 0;
            }
        });

        $form->saved(function (Form $form) {
            $create = $form->isCreating();

            //$this->consumerNotice($form->model()->id, $create ? 'insert' : 'update');

            $success = new MessageBag([
                'title' => '消费者创建成功'
            ]);

            return redirect('/admin/EventSystem/consumer')->with(compact('success'));
        });

        $form->deleting(function (Form $form, $id) {
            //
            //$this->consumerNotice($id, 'delete');
//
//            return response()->json([
//                'status'  => true,
//                'message' => '删除失败，请。。',
//            ]);

        });

        return $form;
    }

    /**
     * @param $id
     * @param $type string 类型 update delete insert
     * @throws \Exception
     */
    public function consumerNotice($id, string $type)
    {
        $base = EventCommon::getBaseUrl($id);
        $url = $base . config("event.consumer_url");
        $data = ['consumer_id' => $id, 'type' => $type];

        EventCommon::apiNotice($url, $data, __FUNCTION__);
    }

    /**
     * @param $consumerId
     * @param $id
     * @param $type string 类型 update delete insert
     * @throws \Exception
     */
    public function subEventNotice($consumerId, $id, string $type)
    {
        $base = EventCommon::getBaseUrl($consumerId);
        $url = $base . config("event.sub_event_url");

        $data = ['sub_event_id' => $id, 'type' => $type];

        EventCommon::apiNotice($url, $data, __FUNCTION__);
    }

    public function setConfig($id, Content $content)
    {
        $subEvents = SubEvent::where('consumer_id', $id)->where('data_status', SubEvent::STATUS_ON)->get();
        //var_dump($subEvents);
        $formatData = [];
        foreach ($subEvents as $subEvent) {
            $formatData[] = [
                Event::find($subEvent->event_id)->name,
                $this->getEventAttr($subEvent, 1),
                $this->getEventAttr($subEvent, 2),
                $this->getEventAttr($subEvent, 3),
                $this->getEventAttr($subEvent, 4),
                $this->getEventAttr($subEvent, 5)
            ];
        }
        $headers = ['事件名称', '类型', '状态', '行为', '扩展属性', '扩展行为'];
        $table = new Table($headers, $formatData);
        $content->row($table);
        return $content
            ->header('消费者订阅信息')
            ->description(Consumer::find($id)->name)
            ->breadcrumb(
                ['text' => '消费者管理', 'url' => '/EventSystem/consumer'],
                ['text' => '属性配置']
            );
    }

    private function getEventAttr($subEvent, $latitude)
    {
        $eventPropertyIds = SubEventProperty::where('sub_event_id', $subEvent->id)
            ->where('status', SubEventProperty::STATUS_ON)
            ->where('basic_event_latitude_id', $latitude)
            ->pluck('event_property_ids')->first();
        if ($eventPropertyIds) {
            $eventPropertyIds = explode(',', $eventPropertyIds);
            $evnetAtrr = EventProperty::where('event_id', $subEvent->event_id)
                ->whereIn('id', $eventPropertyIds)->pluck('name')->toArray();
            return implode(',', $evnetAtrr);
        } else {
            return "*";
        }
    }

    public function setConfigbak($id, Content $content)
    {
        $query = SubEventProperty::query()->where(['consumer_id' => $id, 'status' => SubEventProperty::STATUS_ON]);
        $list = $query->orderBy("sub_event_id")->get()->toArray();
//        $subEventIds = array_column($list, 'sub_event_id');

//        $subEventIds = array_unique($subEventIds);

        //获取事件类型id
        $eventLatitudeIds = array_column($list, 'event_latitude_id');
        //获取事件类型id与basic键值对
        $tempList = EventLatitude::query()->whereIn('id', $eventLatitudeIds)->pluck(
            'basic_event_latitude_id',
            'id'
        )->toArray();

        $basicEventLatitudeList = BasicEventLatitude::query()->pluck('name', 'id')->toArray();
        //事件类型
        $eventTypeList = [];
        foreach ($tempList as $eventLatitudeId => $basicEventLatitudeId) {
            if (isset($basicEventLatitudeList[$basicEventLatitudeId]) && $basicEventLatitudeList[$basicEventLatitudeId]) {
                $eventTypeList[$eventLatitudeId] = $basicEventLatitudeList[$basicEventLatitudeId];
            }
        }
        //获取事件名称
        $event = Event::query()->where('data_status', 1)->pluck('name', 'id')->toArray();

        //获取事件属性id
        $eventPropertys = array_column($list, 'event_property_ids', 'id');


        //获取全部事件属性
        $eventPropertyList = EventProperty::query()->pluck('name', 'id')->toArray();

        $eventPropertyNewList = [];
        foreach ($eventPropertys as $id => $eventProperty) {
            $eventPropertyIds = explode(',', $eventProperty) ?? '';

            if ($eventPropertyIds) {
                foreach ($eventPropertyIds as $item) {
                    $eventPropertyNewList[$id][] = $eventPropertyList[$item] ?? '';
                }
            } else {
                $eventPropertyNewList[$id] = [];
            }
        }

        foreach ($list as &$item) {
            $item['event_name'] = $event[$item['event_id']] ?? '';
            $item['event_latitude_name'] = $eventTypeList[$item['event_latitude_id']] ?? '';
            $item['event_property_list'] = $eventPropertyNewList[$item['id']] ?? [];
        }

        $count = $query->count();
        $gridModel = new GridDataModel($list, $count, [
            'perPage' => 50,
        ]);
        $grid = Admin::grid(
            $gridModel,
            function (Grid $grid) use ($gridModel) {
                $grid->paginate($gridModel->getPerPage());
                $grid->disableFilter();
                $grid->disableCreateButton();
                $grid->disableExport();
                $grid->disableRowSelector();
                $grid->column('id', 'id');
                $grid->column('event_name', '事件名称');
                $grid->column('event_latitude_name', '事件类型');
//                $grid->column('event_property_list', '事件属性')->pluck('name');
                $grid->column('event_property_list', '事件属性')->display(function ($event_property_list) {
                    $html = '';
                    foreach ($event_property_list as $item) {
                        if ($item) {
                            $html .= '<div class="span-label" style="margin:10px: "><span class="label label-success">' . $item . '</span></div>';
                        } else {
                            return '';
                        }
                    }
                    return $html;
                });;
                $grid->disableActions();
            }
        );


        $content->row($grid);
        return $content
            ->header('消费者配置列表')
            ->description(' ')
            ->breadcrumb(['text' => '找好物列表', 'url' => '/TodayNiceGoods/index']);
    }

}